Package org.python.pydev.builder

Source Code of org.python.pydev.builder.PydevInternalResourceDeltaVisitor

/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Created on 11/09/2005
*/
package org.python.pydev.builder;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.python.pydev.builder.pycremover.PycHandlerBuilderVisitor;
import org.python.pydev.core.FileUtilsFileBuffer;
import org.python.pydev.core.callbacks.ICallback0;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.codecompletion.revisited.PythonPathHelper;
import org.python.pydev.plugin.nature.PythonNature;

import com.aptana.shared_core.string.FastStringBuffer;

public abstract class PydevInternalResourceDeltaVisitor extends PyDevBuilderVisitor implements IResourceDeltaVisitor {

    PydevInternalResourceDeltaVisitor(IProgressMonitor monitor, int totalResources) {
        this.monitor = monitor;
        this.totalResources = totalResources;
    }

    //variables used to communicate the progress
    /**
     * this monitor might be set externally so that we can comunicate the progress to the user
     * (set externally)
     */
    public IProgressMonitor monitor;
    /**
     * number of total resources to be visited (only used when the monitor is set)
     * (set externally)
     */
    public int totalResources;
    /**
     * number of resources visited to the moment
     * (updated in this class)
     */
    public int currentResourcesVisited = 0;

    //end variables used to communicate the progress

    /**
     * Visits the resource delta tree determining which files to rebuild (*.py).
     *
     * Subclasses should only reimplement visitChanged, visitAdded and visitRemoved. This method will not be called
     * in the structure provided by pydev.
     *
     * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
     */
    public boolean visit(IResourceDelta delta) throws CoreException {
        if (delta == null) {
            return true;
        }

        IResource resource = delta.getResource();

        if (resource == null) {
            return true;
        }

        int type = resource.getType();

        //related bug https://sourceforge.net/tracker/index.php?func=detail&aid=1238850&group_id=85796&atid=577329

        //the team-support plugins of eclipse use the IResource
        //method setTeamPrivateMember to indicate resources
        //that are only in the project for the team-stuff (e.g. .svn or
        //.cvs or _darcs directories).
        if (resource.isTeamPrivateMember()) {
            return true;
        }

        if (type == IResource.FOLDER) {
            switch (delta.getKind()) {
                case IResourceDelta.REMOVED:
                    memo.put(PyDevBuilderVisitor.DOCUMENT_TIME, System.currentTimeMillis());
                    visitRemovedResource(resource, null, monitor);
                    break;
            //for folders, we don't have to do anything if added or changed (we just treat their children, that should
            //resolve for modules -- we do, however have to treat __init__.py differently).
            }

        } else if (type == IResource.FILE) {
            String ext = resource.getFileExtension();
            if (ext == null) { //resource.getFileExtension() may return null if it has none.
                if (resource instanceof IFile) {
                    PythonPathHelper.markAsPyDevFileIfDetected((IFile) resource);
                }
                return true;
            }

            //only analyze projects with the python nature...
            IProject project = resource.getProject();
            PythonNature nature = PythonNature.getPythonNature(project);

            if (project != null && nature != null) {
                //we just want to make the visit if it is a valid python file and it is in the pythonpath
                if (PythonPathHelper.isValidSourceFile("." + ext)) {

                    boolean isAddOrChange = false;

                    //document time is updated here
                    isAddOrChange = chooseVisit(delta, resource, isAddOrChange);

                    if (isAddOrChange) {
                        //communicate the progress
                        currentResourcesVisited++;
                        FastStringBuffer bufferToCreateString = new FastStringBuffer();
                        PyDevBuilder.communicateProgress(monitor, totalResources, currentResourcesVisited, resource,
                                this, bufferToCreateString);
                    }
                } else if (ext.equals("pyc")) {
                    if (delta.getKind() == IResourceDelta.ADDED) {
                        handleAddedPycFiles(resource, nature);
                    }
                }
            }
        }

        return true;
    }

    /**
     * When handling pyc files, we do a simpler handling and go directly to the pyc builder visitor to check
     * if the pyc should be removed.
     */
    protected void handleAddedPycFiles(IResource resource, PythonNature nature) {
        try {
            //we do that because we may have an added .pyc without a correspondent .py file
            PycHandlerBuilderVisitor pycVisitor = new PycHandlerBuilderVisitor();
            pycVisitor.visitingWillStart(monitor, false, nature);
            try {
                pycVisitor.visitAddedResource(resource, null, monitor); //doc is not used in pyc remover
            } finally {
                pycVisitor.visitingEnded(monitor);
            }
        } catch (Exception e) {
            Log.log(e);
        }
    }

    /**
     * This will use the internal builders to traverse the delta. Note that the resource is always a valid
     * python file and is also always located in the pythonpath.
     */
    protected boolean chooseVisit(IResourceDelta delta, IResource resource, boolean isAddOrChange) {
        switch (delta.getKind()) {
            case IResourceDelta.ADDED:
                ICallback0<IDocument> doc = FileUtilsFileBuffer.getDocOnCallbackFromResource(resource);
                memo.put(PyDevBuilderVisitor.DOCUMENT_TIME, System.currentTimeMillis());
                visitAddedResource(resource, doc, monitor);
                isAddOrChange = true;
                break;
            case IResourceDelta.CHANGED:
                doc = FileUtilsFileBuffer.getDocOnCallbackFromResource(resource);
                memo.put(PyDevBuilderVisitor.DOCUMENT_TIME, System.currentTimeMillis());
                visitChangedResource(resource, doc, monitor);
                isAddOrChange = true;
                break;
            case IResourceDelta.REMOVED:
                memo.put(PyDevBuilderVisitor.DOCUMENT_TIME, System.currentTimeMillis());
                visitRemovedResource(resource, null, monitor);
                break;
        }
        return isAddOrChange;
    }

}
TOP

Related Classes of org.python.pydev.builder.PydevInternalResourceDeltaVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.